<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Babylon.js Editor Preview</title>
    
    <script src="./node_modules/es6-promise/dist/es6-promise.auto.js" type="text/javascript"></script>
    <script src="./node_modules/systemjs/dist/system.src.js" type="text/javascript"></script>

    <script src="./node_modules/socket.io-client/dist/socket.io.js" type="text/javascript"></script>
    <script src="./node_modules/ccapture.js/build/CCapture.all.min.js" type="text/javascript"></script>

    <style>
        html, body {
            position: fixed;
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            touch-action: none;
            -ms-touch-action: none;
        }

        #renderCanvas {
            position: fixed;
            width: 100%;
            height: 100%;
            top: 0;
        }
    </style>
</head>
<body>
    <canvas id="renderCanvas"></canvas>
    <script type="text/javascript">
        // Accessible variables from parent window
        var renderScene = true;
        var effectiveScene = null;
        var gotScene = null;
        var captureSpector = null;

        var capturer = new CCapture({ format: 'webm', framerate: 60, display: true });

        var tools = null;
        var requests = null;

        // Opener or Parent ?
        if (!opener && parent !== window) {
            opener = parent;
        }
        
        System.config({
            paths: {
                "babylonjs": "./node_modules/babylonjs/babylon.max.js",
                "babylonjs-gui": "./node_modules/babylonjs-gui/babylon.gui.min.js",
                "babylonjs-materials": "./node_modules/babylonjs-materials/babylonjs.materials.min.js",
                "babylonjs-procedural-textures": "./node_modules/babylonjs-procedural-textures/babylonjs.proceduralTextures.js",
                "babylonjs-post-process": "./node_modules/babylonjs-post-process/babylonjs.postProcess.js",
                "babylonjs-loaders": "./node_modules/babylonjs-loaders/babylonjs.loaders.js",
                "cannon": "./node_modules/cannon/build/cannon.min.js",
                "spectorjs": "./node_modules/spectorjs/dist/spector.bundle.js",
                "earcut": "./node_modules/earcut/dist/earcut.min.js",
                "oimo": "./node_modules/babylonjs/Oimo.js",
                "javascript-astar": "./node_modules/javascript-astar/astar.js",
                "litegraph.js": "./node_modules/litegraph.js/build/litegraph.js"
            },
            packages: {
                "./build/src/": {
                    defaultExtension: "js"
                },
                "./node_modules/babylonjs-loaders/": {
                    format: "cjs",
                    main: "babylonjs.loaders.js",
                    format: "global"
                }
            },
            meta: {
                "cannon": { format: "global" },
                "javascript-astar": { format: "global" }
            }
        });

        // Loads the Babylon.js Scenes
        var loadScene = function (sceneFile) {
            var engine = new BABYLON.Engine(document.getElementById('renderCanvas'));
            window.addEventListener("resize", function () {
                engine.resize();
            });

            // Load Extensions Manager and then all extensions
            var promises = [];
            var files = [
                "./build/src/extensions/index.js",
                "./build/src/extensions/spector/spector-debug.js"
            ];

            for (var i = 0; i < files.length; i++) {
                promises.push(System.import(files[i]));
            }

            Promise.all(promises).then(function () {
                // Import scene
                if (!sceneFile || !BABYLON.FilesInputStore.FilesToLoad[sceneFile.name.toLowerCase()])
                    return;
                
                BABYLON.SceneLoader.Load('file:', sceneFile.name, engine, function (scene) {
                    effectiveScene = scene;
                    
                    System.import('./build/src/extensions/extensions.js').then(function (extensions) {
                        // Apply
                        var readProject = function (project) {
                            BABYLON.Tools.ReadFile(project, function (data) {
                                extensions.default.RoolUrl = 'file:';
                                extensions.default.ApplyExtensions(scene, JSON.parse(data).customMetadatas);

                                // Run scene
                                scene.executeWhenReady(function () {
                                    scene.activeCamera.attachControl(engine.getRenderingCanvas());
                                    engine.runRenderLoop(function () {
                                        if (renderScene)
                                            scene.render();
                                    });

                                    if (gotScene) {
                                        gotScene(scene);
                                    } else {
                                        // Windowed test
                                        engine.getRenderingCanvas().addEventListener('blur', function (ev) {
                                            renderScene = false;
                                        });

                                        engine.getRenderingCanvas().addEventListener('focus', function (ev) {
                                            renderScene = true;
                                        });
                                    }
                                });

                                // Spectorjs
                                captureSpector = function (done) {
                                    const spectorExt = extensions.default.RequestExtension(scene, 'SpectorDebug');
                                    spectorExt.spector.onCapture.add(function (c) {
                                        done(c, spectorExt.spector.logger);
                                    });
                                    spectorExt.spector.startCapture(engine.getRenderingCanvas(), false);
                                };
                            });
                        };

                        // TODO: serialize / parse GUI
                        // Import UI
                        // opener.editor.guiFiles.forEach(function (gf) {
                        //     var reader = new FileReader();
                        //     reader.onload = function (data) {
                        //         System.import("babylonjs-gui").then(function (e) {
                        //             e.AdvancedDynamicTexture.Parse(data.target.result);
                        //             getFileByExtension(BABYLON.FilesInputStore.FilesToLoad, 'editorproject', function (project) {
                        //                 readProject(project);
                        //             });
                        //         });
                        //     };
                        //     reader.readAsText(gf);
                        // });
                        var project = getFileByExtension(BABYLON.FilesInputStore.FilesToLoad, 'editorproject');
                        readProject(project);
                    });
                });
            });
        };

        // Returns the scene file
        var getFileByExtension = function (files, extension) {
            if (opener) {
                switch (extension) {
                    case 'babylon': return opener.editor.sceneFile;
                    case 'editorproject': return opener.editor.projectFile;
                    default: throw new Error('Cannot get file with extension "' + extension, '"');
                }
            } else {
                for (var thing in files) {
                    var file = tools.CreateFile(files[thing], thing);
                    if (tools.GetFileExtension(file.name) === extension) {
                        return file;
                    }
                }
            }
        };

        // Load Babylon.js
        // Get scene file
        // Run sockets
        var promises = [];
        promises.push(System.import("babylonjs"));
        promises.push(System.import("babylonjs-gui"));
        promises.push(System.import("cannon"));
        Promise.all(promises).then(function (e) {
            return System.import("babylonjs-procedural-textures");
        }).then(function () {
            return System.import("babylonjs-materials");
        }).then(function () {
            return System.import("babylonjs-post-process");
        }).then(function () {
            return System.import("babylonjs-loaders");
        }).then(function () {
            return System.import('./build/src/editor/tools/tools.js').then(function (t) {
                tools = t.default;
            });
        }).then(function () {
            return System.import('./build/src/editor/tools/request.js').then(function (r) {
                requests = r.default;
            });
        }).then(function () {
            return System.import('./node_modules/jquery/dist/jquery.js');
        }).then(function () {
            if (!window.frameElement && tools.IsElectron()) {
                return requests.Get('/devTools');
            }
        }).then(function () {
            tools.isFileApiSupported(true);

            if (opener) {
                BABYLON.FilesInputStore.FilesToLoad = opener.BABYLON.FilesInputStore.FilesToLoad;

                var sceneFile = getFileByExtension(BABYLON.FilesInputStore.FilesToLoad, 'babylon');
                loadScene(sceneFile);
            }
            else {
                var socket = io('/client');
                socket.on('request-scene', (files) => {
                    // Import Editor tools
                    for (var thing in files) {
                        var file = tools.CreateFile(files[thing], thing);
                        BABYLON.FilesInputStore.FilesToLoad[thing] = file;
                    }

                    var sceneFile = getFileByExtension(files, 'babylon');
                    loadScene(sceneFile);
                });
            }
        });
    </script>
</body>
</html>